﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Networking.Sockets;
using Windows.Storage.Streams;

namespace TakePhotoTogether.Communication
{
    public class StreamSocketConnection : ConnectionChannel
    {
        private StreamSocket streamSocket = null;
        private DataWriter dataWriter = null;
        private DataReader dataReader = null;

        public StreamSocketConnection(StreamSocket receivedSocket)
        {
            streamSocket = receivedSocket;

            if (streamSocket != null)
            {
                /** Setup variables related to socket usage **/
                var inputStream = streamSocket.InputStream;
                dataReader = new DataReader(inputStream);

                var outputStream = streamSocket.OutputStream;
                dataWriter = new DataWriter(outputStream);
            }
        }

        public override bool IsEnabled()
        {
            return streamSocket != null && dataWriter != null;
        }

        public override async Task ReadPacket()
        {
            Debug.WriteLine("SocketManager::ReadPacket - ");

            uint sizeInt = sizeof(int);
            //Debug.WriteLine("SocketManager::PacketReceivingLoop - loop start");
            await dataReader.LoadAsync(sizeInt);
            int messageType = dataReader.ReadInt32();

            //Debug.WriteLine("SocketManager::PacketReceivingLoop - received message: " + messageType);

            if (messageType <= 0)
            {
                return;
            }

            await dataReader.LoadAsync(sizeInt);
            int dataSize = dataReader.ReadInt32();
            //Debug.WriteLine("SocketManager::PacketReceivingLoop - data size: " + dataSize);

            await dataReader.LoadAsync((uint)dataSize);

            byte[] data = new byte[dataSize];
            dataReader.ReadBytes(data);

            //Debug.WriteLine("SocketManager::PacketReceivingLoop - Send data to listener");
            OnPacketReceived(data, messageType);
        }

        public override async Task SendPacket(DataPacket packet)
        {
            Debug.WriteLine("BluetoothConnection::SendPacket - " + packet.MessageType);

            byte[] data = null;

            if (packet != null)
            {
                //Debug.WriteLine("SocketManager::PacketSendingLoop - loop 1");
                // First send Message type: Stream or Sync
                dataWriter.WriteInt32(packet.MessageType);
                //Debug.WriteLine("SocketManager::PacketSendingLoop - loop 2");

                // Then the payload must be sent
                if (packet.Payload != null)
                {
                    data = packet.Payload.ToBytes();
                    dataWriter.WriteInt32(data.Length);
                    dataWriter.WriteBytes(data);
                }
                else
                {
                    dataWriter.WriteInt32(0);
                }

                uint bytesWritten = await dataWriter.StoreAsync();
            }
        }

        public override void Dispose()
        {
            if (dataReader != null)
            {
                dataReader.Dispose();
            }

            if (dataWriter != null)
            {
                dataWriter.Dispose();
            }

            if (streamSocket != null)
            {
                streamSocket.Dispose();
            }

            dataReader = null;
            dataWriter = null;
            streamSocket = null;
        }
    }
}
